package com.ljx.recruitment.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljx.recruitment.common.domain.vo.resp.PageResp;
import com.ljx.recruitment.common.enums.CommonStatusTypeEnum;
import com.ljx.recruitment.user.domain.entity.Menu;
import com.ljx.recruitment.user.domain.entity.Permission;
import com.ljx.recruitment.user.domain.entity.Permission;
import com.ljx.recruitment.user.domain.vo.req.PermissionPageReq;
import com.ljx.recruitment.user.domain.vo.req.PermissionSubmitReq;
import com.ljx.recruitment.user.domain.vo.req.PermissionToRoleReq;
import com.ljx.recruitment.user.domain.vo.resp.PermissionTree;
import com.ljx.recruitment.user.enums.PermissionModuleEnum;
import com.ljx.recruitment.user.mapper.PermissionMapper;
import com.ljx.recruitment.user.service.PermissionService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: LiJunXi
 * @Description:
 * @Date: 2024-10-31  14:24
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public List<Long> getPermissionIdByRoleIds(List<Long> roleIds) {
        return permissionMapper.getPermissionByUserId(roleIds);
    }

    @Override
    public List<Permission> getPermissionByIds(List<Long> ids) {
        if (ids.isEmpty()) {
            return new ArrayList<>();
        }
        return listByIds(ids);
    }

    @Override
    public Permission submit(PermissionSubmitReq req) {
        Permission permission;
        if (Objects.isNull(req.getId())){
            permission = BeanUtil.copyProperties(req, Permission.class);
            permissionMapper.insert(permission);
        } else {
            permission = permissionMapper.selectById(req.getId());
            BeanUtils.copyProperties(req, permission);
            permissionMapper.updateById(permission);
        }

        return permission;
    }

    @Override
    public PageResp<Permission> getPage(PermissionPageReq req) {
        LambdaQueryWrapper<Permission> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByAsc(Permission::getModule);
        if (Objects.nonNull(req.getKey())){
            lambdaQueryWrapper.like(Permission::getName, req.getKey());
        }
        Page<Permission> page = permissionMapper.selectPage(new Page<>(req.getCurrPage(), req.getPageSize()), lambdaQueryWrapper);
        return PageResp.<Permission>builder()
                .total(page.getTotal())
                .list(page.getRecords())
                .build();
    }

    @Override
    public List<String> getModule() {
        return Arrays.stream(PermissionModuleEnum.values())
                .map(PermissionModuleEnum::getKey)
                .collect(Collectors.toList());
    }

    @Override
    public List<PermissionTree> getTree() {
        Map<String, List<Permission>> permissionMap = permissionMapper.selectList(new LambdaQueryWrapper<Permission>()
                .eq(Permission::getStatus, CommonStatusTypeEnum.NORMAL.getKey()))
                .stream()
                .collect(Collectors.groupingBy(Permission::getModule));
        List<PermissionTree> res = new ArrayList<>();
        for (String item : getModule()) {
            PermissionTree permissionTree = new PermissionTree();
            permissionTree.setId(null);
            permissionTree.setName(item);
            permissionTree.setChildren(BeanUtil.copyToList(permissionMap.get(item), PermissionTree.class));
            res.add(permissionTree);
        }
        return res;
    }

    @Override
    @Transactional
    public void allocationToRole(PermissionToRoleReq req) {
        permissionMapper.deleteRolePermission(req.getRoleId());
        if (CollUtil.isEmpty(req.getPermissionIds())){
            return;
        }
        List<Long> permissionIds = req.getPermissionIds()
                .stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        permissionMapper.allocationToRole(req.getRoleId(), permissionIds);
    }

    @Override
    public List<Permission> getPermissionByNames(List<String> permissionNames) {
        if (CollectionUtil.isEmpty(permissionNames)) {
            return new ArrayList<>();
        }
        return permissionMapper.selectList(new LambdaQueryWrapper<Permission>()
                .in(Permission::getName, permissionNames));
    }
}
